package com.css.zfzx.sjcj.modules.repository.impl;

import com.css.bpm.platform.api.local.PlatformAPI;
import com.css.bpm.platform.org.dept.repository.entity.DeptEntity;
import com.css.bpm.platform.org.division.repository.DivisionRepository;
import com.css.bpm.platform.org.division.repository.entity.DivisionEntity;
import com.css.bpm.platform.org.role.repository.entity.RoleEntity;
import com.css.bpm.platform.utils.PlatformSessionUtils;
import com.css.zfzx.sjcj.common.utils.ServerUtil;
import com.css.zfzx.sjcj.modules.pojo.PcStatisticsFillEntity;
import com.css.zfzx.sjcj.modules.pojo.QueryVo;
import com.css.zfzx.sjcj.modules.repository.PcStatisticsFillNativeRepository;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;

/**
 * @Description: pc-statistics
 * @Author: lhl
 * @CreateDate: 2021/8/3 9:22
 */
@Repository
@PropertySource("classpath:platform-config.yml")
public class PcStatisticsFillNativeRepositoryImpl<T> implements PcStatisticsFillNativeRepository<T> {
    @PersistenceContext
    private EntityManager em;
    @Value("${role.superCode}")
    private String superCode;
    @Value("${role.provinceCode}")
    private String provinceCode;
    @Value("${role.cityCode}")
    private String cityCode;
    @Value("${role.areaCode}")
    private String areaCode;
    @Autowired
    private DivisionRepository divisionRepository;
    private static final Logger log = LoggerFactory.getLogger(PcProgressFillNativeRepositoryImpl.class);
    @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}")
    private int BATCH_SIZE;

    @Override
    @Transactional
    public <S extends T> Iterable<S> batchUpdate(Iterable<S> var1) {
        Iterator<S> iterator = var1.iterator();
        int index = 0;
        while (iterator.hasNext()) {
            em.merge(iterator.next());
            index++;
            if (index % BATCH_SIZE == 0) {
                em.flush();
                em.clear();
            }
        }
        if (index % BATCH_SIZE != 0) {
            em.flush();
            em.clear();
        }
        return var1;
    }

    @Override
    @Transactional
    public <S extends T> Iterable<S> batchSave(Iterable<S> var1) {
        Iterator<S> iterator = var1.iterator();
        int index = 0;
        while (iterator.hasNext()) {
            em.persist(iterator.next());
            index++;
            if (index % BATCH_SIZE == 0) {
                em.flush();
                em.clear();
            }
        }
        if (index % BATCH_SIZE != 0) {
            em.flush();
            em.clear();
        }
        return var1;
    }
    @Override
    public Page<PcStatisticsFillEntity> find(QueryVo queryVo,String userId, int curPage, int pageSize,String sort,
                                          String order) {
        StringBuilder sql = new StringBuilder("select * from pc_statistics_fill ");
        StringBuilder whereSql = new StringBuilder(" where 1=1 ");
        if (StringUtils.isNotEmpty(queryVo.getTaskName())){
            whereSql.append(" and task_name = :taskName");
        }
        if (StringUtils.isNotEmpty(queryVo.getProvince())){
            whereSql.append(" and province = :province");
        }
        if (StringUtils.isNotEmpty(queryVo.getCity())){
            whereSql.append(" and city = :city");
        }
        if (StringUtils.isNotEmpty(queryVo.getArea())){
            whereSql.append(" and area = :area");
        }
        if (StringUtils.isNotEmpty(queryVo.getStartTime())){
            whereSql.append(" and upload_time >= :startTime");
        }
        if (StringUtils.isNotEmpty(queryVo.getEndTime())){
            whereSql.append(" and upload_time <= :endTime");
        }
        if ("Y".equals(queryVo.getIsPioneer())){
            whereSql.append(" and is_pioneer = 'Y'");
        }
        whereSql.append(" and is_valid = 1 ");
        List<RoleEntity> roles = PlatformAPI.getOrgAPI().getUserAPI().getRoles(userId);
        //是否为超级管理员
        boolean containtRole = ServerUtil.isContaintRole(roles, superCode);
        //是否为省级管理员
        boolean containtRolePro = ServerUtil.isContaintRole(roles, provinceCode);
        //是否为市级管理员
        boolean containtRoleCity = ServerUtil.isContaintRole(roles, cityCode);
        //是否为县级管理员
        boolean containtRoleArea = ServerUtil.isContaintRole(roles, areaCode);
        if (!containtRole) {
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                whereSql.append(" and create_user =:userId");
            }
            if (containtRolePro) {
                whereSql.append(" and province like :authProvince");
            }
            if (containtRoleCity) {
                whereSql.append(" and city like :authCity");
            }
            if (containtRoleArea) {
                whereSql.append(" and area like :authArea");
            }
        }
        if (!StringUtils.isEmpty(sort)) {
            whereSql.append(" order by " + sort + " " + order);
        }
        //whereSql.append(" limit " + (curPage-1)*pageSize + "," + pageSize);
        Query query = this.em.createNativeQuery(sql.append(whereSql).toString(), PcStatisticsFillEntity.class);
        StringBuilder countSql = new StringBuilder("select count(*) from pc_statistics_fill ");
        Query countQuery = this.em.createNativeQuery(countSql.append(whereSql).toString());
        if (StringUtils.isNotEmpty(queryVo.getTaskName())){
            query.setParameter("taskName",queryVo.getTaskName());
            countQuery.setParameter("taskName",queryVo.getTaskName());
        }
        if (StringUtils.isNotEmpty(queryVo.getProvince())){
            query.setParameter("province",queryVo.getProvince());
            countQuery.setParameter("province",queryVo.getProvince());
        }
        if (StringUtils.isNotEmpty(queryVo.getCity())){
            query.setParameter("city",queryVo.getCity());
            countQuery.setParameter("city",queryVo.getCity());
        }
        if (StringUtils.isNotEmpty(queryVo.getArea())){
            query.setParameter("area",queryVo.getArea());
            countQuery.setParameter("area",queryVo.getArea());
        }
        if (StringUtils.isNotEmpty(queryVo.getStartTime())){
            query.setParameter("startTime",queryVo.getStartTime());
            countQuery.setParameter("startTime",queryVo.getStartTime());
        }
        if (StringUtils.isNotEmpty(queryVo.getEndTime())){
            query.setParameter("endTime",queryVo.getEndTime());
            countQuery.setParameter("endTime",queryVo.getEndTime());
        }
        if (!containtRole) {
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                query.setParameter("userId", userId);
                countQuery.setParameter("userId", userId);
            }
            DeptEntity mainDept = PlatformAPI.getOrgAPI().getUserAPI().getMainDept(userId);
            String divisionId = mainDept.getDivisionId();
            DivisionEntity validDivisionById = divisionRepository.findValidDivisionById(divisionId);
            String divisionName = validDivisionById.getDivisionName();
            if (containtRolePro) {
                query.setParameter("authProvince", "%" + divisionName + "%");
                countQuery.setParameter("authProvince", "%" + divisionName + "%");
            }
            if (containtRoleCity) {
                query.setParameter("authCity", "%" + divisionName + "%");
                countQuery.setParameter("authCity", "%" + divisionName + "%");
            }
            if (containtRoleArea) {
                query.setParameter("authArea", "%" + divisionName + "%");
                countQuery.setParameter("authArea", "%" + divisionName + "%");
            }
        }
        Pageable pageable = PageRequest.of(curPage - 1, pageSize);
        query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
        query.setMaxResults(pageable.getPageSize());
        List<PcStatisticsFillEntity> list = query.getResultList();
        BigInteger count = (BigInteger) countQuery.getSingleResult();
        Page<PcStatisticsFillEntity> pcPage = new PageImpl<>(list, pageable, count.longValue());
        return pcPage;
    }

    @Override
    public List<PcStatisticsFillEntity> findNoPage(QueryVo queryVo, String userId) {
        StringBuilder sql = new StringBuilder("select * from pc_statistics_fill ");
        StringBuilder whereSql = new StringBuilder(" where 1=1 ");
        if (StringUtils.isNotEmpty(queryVo.getTaskName())){
            whereSql.append(" and task_name = :taskName");
        }
        if (StringUtils.isNotEmpty(queryVo.getProvince())){
            whereSql.append(" and province = :province");
        }
        if (StringUtils.isNotEmpty(queryVo.getCity())){
            whereSql.append(" and city = :city");
        }
        if (StringUtils.isNotEmpty(queryVo.getArea())){
            whereSql.append(" and area = :area");
        }
        if (StringUtils.isNotEmpty(queryVo.getStartTime())){
            whereSql.append(" and upload_time >= :startTime");
        }
        if (StringUtils.isNotEmpty(queryVo.getEndTime())){
            whereSql.append(" and upload_time <= :endTime");
        }
        if ("Y".equals(queryVo.getIsPioneer())){
            whereSql.append(" and is_pioneer = 'Y'");
        }
        whereSql.append(" and is_valid = 1 ");
        List<RoleEntity> roles = PlatformAPI.getOrgAPI().getUserAPI().getRoles(userId);
        //是否为超级管理员
        boolean containtRole = ServerUtil.isContaintRole(roles, superCode);
        //是否为省级管理员
        boolean containtRolePro = ServerUtil.isContaintRole(roles, provinceCode);
        //是否为市级管理员
        boolean containtRoleCity = ServerUtil.isContaintRole(roles, cityCode);
        //是否为县级管理员
        boolean containtRoleArea = ServerUtil.isContaintRole(roles, areaCode);
        if (!containtRole) {
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                whereSql.append(" and create_user =:userId");
            }
            if (containtRolePro) {
                whereSql.append(" and province like :authProvince");
            }
            if (containtRoleCity) {
                whereSql.append(" and city like :authCity");
            }
            if (containtRoleArea) {
                whereSql.append(" and area like :authArea");
            }
        }
        Query query = this.em.createNativeQuery(sql.append(whereSql).toString(), PcStatisticsFillEntity.class);
        if (StringUtils.isNotEmpty(queryVo.getTaskName())){
            query.setParameter("taskName",queryVo.getTaskName());
        }
        if (StringUtils.isNotEmpty(queryVo.getProvince())){
            query.setParameter("province",queryVo.getProvince());
        }
        if (StringUtils.isNotEmpty(queryVo.getCity())){
            query.setParameter("city",queryVo.getCity());
        }
        if (StringUtils.isNotEmpty(queryVo.getArea())){
            query.setParameter("area",queryVo.getArea());
        }
        if (StringUtils.isNotEmpty(queryVo.getStartTime())){
            query.setParameter("startTime",queryVo.getStartTime());
        }
        if (StringUtils.isNotEmpty(queryVo.getEndTime())){
            query.setParameter("endTime",queryVo.getEndTime());
        }
        if (!containtRole) {
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                query.setParameter("userId", userId);
            }
            DeptEntity mainDept = PlatformAPI.getOrgAPI().getUserAPI().getMainDept(userId);
            String divisionId = mainDept.getDivisionId();
            DivisionEntity validDivisionById = divisionRepository.findValidDivisionById(divisionId);
            String divisionName = validDivisionById.getDivisionName();
            if (containtRolePro) {
                query.setParameter("authProvince", "%" + divisionName + "%");
            }
            if (containtRoleCity) {
                query.setParameter("authCity", "%" + divisionName + "%");
            }
            if (containtRoleArea) {
                query.setParameter("authArea", "%" + divisionName + "%");
            }
        }
        List<PcStatisticsFillEntity> list = query.getResultList();
        return list;
    }
}
